<template>
  <div class="admin-page">
    <NavBar />
    
    <a-layout-content class="content">
      <div class="admin-container">
        <div class="header">
          <h1 class="title">
            <setting-outlined /> 管理员面板
          </h1>
          <p class="subtitle">数据库构建与管理</p>
        </div>

        <!-- 数据库状态卡片 -->
        <a-row :gutter="24" style="margin-bottom: 24px;">
          <a-col :span="12">
            <a-card class="status-card">
              <template #title>
                <database-outlined style="color: #1890ff; margin-right: 8px;" />
                BLAST 数据库状态
              </template>
              <template #extra>
                <a-tag :color="blastStatus.exists ? 'success' : 'error'">
                  {{ blastStatus.exists ? '已构建' : '未构建' }}
                </a-tag>
              </template>
              <div v-if="blastStatus.metadata">
                <a-descriptions :column="1" size="small" bordered>
                  <a-descriptions-item label="序列数量">
                    {{ blastStatus.metadata.sequence_count?.toLocaleString() || '-' }}
                    <a-tag v-if="blastStatus.metadata.note" color="orange" style="margin-left: 8px;">
                      自动提取
                    </a-tag>
                  </a-descriptions-item>
                  <a-descriptions-item label="构建时间" v-if="blastStatus.metadata.build_date">
                    {{ formatDate(blastStatus.metadata.build_date) }}
                  </a-descriptions-item>
                  <a-descriptions-item label="BLAST版本" v-if="blastStatus.metadata.blast_version">
                    {{ blastStatus.metadata.blast_version }}
                  </a-descriptions-item>
                  <a-descriptions-item label="说明" v-if="blastStatus.metadata.note">
                    <a-tag color="orange">{{ blastStatus.metadata.note }}</a-tag>
                  </a-descriptions-item>
                </a-descriptions>
              </div>
              <div v-else-if="blastStatus.exists">
                <a-alert
                  :message="blastStatus.message || '数据库已构建，但缺少元数据文件'"
                  type="warning"
                  show-icon
                  :description="'建议重新构建数据库以生成完整的元数据信息'"
                />
              </div>
              <a-empty v-else description="数据库未构建" :image="false" />
            </a-card>
          </a-col>

          <a-col :span="12">
            <a-card class="status-card">
              <template #title>
                <experiment-outlined style="color: #52c41a; margin-right: 8px;" />
                Foldseek 数据库状态
              </template>
              <template #extra>
                <a-tag :color="foldseekStatus.exists ? 'success' : 'error'">
                  {{ foldseekStatus.exists ? '已构建' : '未构建' }}
                </a-tag>
              </template>
              <div v-if="foldseekStatus.metadata">
                <a-descriptions :column="1" size="small" bordered>
                  <a-descriptions-item label="PDB文件数">
                    {{ foldseekStatus.metadata.pdb_file_count?.toLocaleString() || '-' }}
                    <a-tag v-if="foldseekStatus.metadata.note" color="orange" style="margin-left: 8px;">
                      自动提取
                    </a-tag>
                  </a-descriptions-item>
                  <a-descriptions-item label="构建时间" v-if="foldseekStatus.metadata.build_date">
                    {{ formatDate(foldseekStatus.metadata.build_date) }}
                  </a-descriptions-item>
                  <a-descriptions-item label="数据库大小" v-if="foldseekStatus.metadata.database_size">
                    {{ foldseekStatus.metadata.database_size }}
                  </a-descriptions-item>
                  <a-descriptions-item label="说明" v-if="foldseekStatus.metadata.note">
                    <a-tag color="orange">{{ foldseekStatus.metadata.note }}</a-tag>
                  </a-descriptions-item>
                </a-descriptions>
              </div>
              <div v-else-if="foldseekStatus.exists">
                <a-alert
                  :message="foldseekStatus.message || '数据库已构建，但缺少元数据文件'"
                  type="warning"
                  show-icon
                  :description="'建议重新构建数据库以生成完整的元数据信息'"
                />
              </div>
              <a-empty v-else description="数据库未构建" :image="false" />
            </a-card>
          </a-col>
        </a-row>

        <!-- 数据库构建操作 -->
        <a-card class="action-card" title="数据库构建操作">
          <a-space direction="vertical" size="large" style="width: 100%;">
            <!-- BLAST数据库构建 -->
            <a-card size="small" :bordered="true">
              <template #title>
                <rocket-outlined style="color: #1890ff;" /> 
                BLAST 数据库构建
              </template>
              <template #extra>
                <a-button 
                  type="primary" 
                  :loading="buildingBlast"
                  :disabled="buildingBlast || buildingFoldseek"
                  @click="handleBuildBlast"
                >
                  <template #icon><tool-outlined /></template>
                  {{ buildingBlast ? '构建中...' : '开始构建' }}
                </a-button>
              </template>
              <a-alert
                message="BLAST数据库用于蛋白质序列比对搜索"
                description="构建过程会从MySQL数据库导出所有蛋白质序列，生成FASTA文件并创建BLAST索引。此操作可能需要几分钟到几十分钟，取决于数据量大小。"
                type="info"
                show-icon
                style="margin-bottom: 12px;"
              />
            </a-card>

            <!-- Foldseek数据库构建 -->
            <a-card size="small" :bordered="true">
              <template #title>
                <experiment-outlined style="color: #52c41a;" /> 
                Foldseek 数据库构建
              </template>
              <template #extra>
                <a-button 
                  type="primary" 
                  :loading="buildingFoldseek"
                  :disabled="buildingBlast || buildingFoldseek"
                  @click="handleBuildFoldseek"
                >
                  <template #icon><tool-outlined /></template>
                  {{ buildingFoldseek ? '构建中...' : '开始构建' }}
                </a-button>
              </template>
              <a-alert
                message="Foldseek数据库用于蛋白质结构相似性搜索"
                description="构建过程会扫描所有PDB文件，创建Foldseek结构数据库和索引。此操作可能需要较长时间，取决于PDB文件数量。"
                type="info"
                show-icon
                style="margin-bottom: 12px;"
              />
            </a-card>

            <!-- 一键构建所有 -->
            <a-card size="small" :bordered="true">
              <template #title>
                <thunderbolt-outlined style="color: #faad14;" /> 
                一键构建所有数据库
              </template>
              <template #extra>
                <a-button 
                  type="primary" 
                  danger
                  :loading="buildingBlast || buildingFoldseek"
                  :disabled="buildingBlast || buildingFoldseek"
                  @click="handleBuildAll"
                >
                  <template #icon><thunderbolt-outlined /></template>
                  构建所有
                </a-button>
              </template>
              <a-alert
                message="同时构建BLAST和Foldseek数据库"
                description="警告：此操作将依次构建所有搜索数据库，耗时较长。建议在数据更新后执行，以确保搜索功能使用最新的数据。"
                type="warning"
                show-icon
              />
            </a-card>
          </a-space>
        </a-card>

        <!-- 构建日志 -->
        <a-card 
          class="log-card" 
          title="构建日志"
          v-if="buildLogs.length > 0"
        >
          <div class="terminal">
            <div 
              v-for="(log, index) in buildLogs" 
              :key="index" 
              :class="['log-entry', `log-${log.level || 'info'}`]"
            >
              <span class="log-time">{{ formatTime(log.timestamp) }}</span>
              <span class="log-level">{{ getLevelIcon(log.level || 'info') }}</span>
              <span class="log-message">{{ log.message }}</span>
            </div>
            <div ref="logBottom"></div>
          </div>
        </a-card>

        <!-- 使用说明 -->
        <a-card class="help-card" title="使用说明">
          <a-collapse>
            <a-collapse-panel key="1" header="何时需要构建数据库？">
              <ul>
                <li>首次使用搜索功能时</li>
                <li>上传新的CSV数据后（建议重新构建以更新索引）</li>
                <li>添加或更新PDB文件后（需要重新构建Foldseek数据库）</li>
                <li>定期更新（建议每周或每月重新构建）</li>
              </ul>
            </a-collapse-panel>
            <a-collapse-panel key="2" header="构建过程说明">
              <ul>
                <li><strong>BLAST构建</strong>：从MySQL导出序列 → 转换为FASTA → 创建BLAST索引</li>
                <li><strong>Foldseek构建</strong>：扫描PDB文件 → 创建结构数据库 → 生成搜索索引</li>
                <li>构建过程中请勿关闭页面，完成后会自动刷新状态</li>
              </ul>
            </a-collapse-panel>
            <a-collapse-panel key="3" header="注意事项">
              <ul>
                <li>构建过程可能需要较长时间，请耐心等待</li>
                <li>确保服务器有足够的磁盘空间</li>
                <li>构建过程中建议不要执行其他数据库操作</li>
                <li>如构建失败，请查看日志并检查相关工具是否已正确安装</li>
              </ul>
            </a-collapse-panel>
          </a-collapse>
        </a-card>
      </div>
    </a-layout-content>
  </div>
</template>

<script setup>
import { ref, onMounted, nextTick } from 'vue'
import { message, Modal } from 'ant-design-vue'
import axiosInstance from '../utils/axios'
import NavBar from '../components/NavBar.vue'
import {
  SettingOutlined,
  DatabaseOutlined,
  ExperimentOutlined,
  RocketOutlined,
  ToolOutlined,
  ThunderboltOutlined
} from '@ant-design/icons-vue'

const buildingBlast = ref(false)
const buildingFoldseek = ref(false)
const blastStatus = ref({ exists: false, metadata: null, metadata_status: 'missing', message: null })
const foldseekStatus = ref({ exists: false, metadata: null, metadata_status: 'missing', message: null })
const buildLogs = ref([])
const logBottom = ref(null)

// 获取数据库状态
const fetchDbStatus = async () => {
  try {
    const response = await axiosInstance.get('/api/admin/db/status')
    blastStatus.value = {
      exists: response.data.blast.exists,
      metadata: response.data.blast.metadata,
      metadata_status: response.data.blast.metadata_status || 'missing',
      message: response.data.blast.message || null
    }
    foldseekStatus.value = {
      exists: response.data.foldseek.exists,
      metadata: response.data.foldseek.metadata,
      metadata_status: response.data.foldseek.metadata_status || 'missing',
      message: response.data.foldseek.message || null
    }
  } catch (error) {
    console.error('获取数据库状态失败:', error)
    message.error('获取数据库状态失败')
  }
}

// 添加日志
const addLog = (message, level = 'info') => {
  buildLogs.value.push({
    timestamp: new Date().toISOString(),
    level,
    message
  })
  // 自动滚动到底部
  nextTick(() => {
    if (logBottom.value) {
      logBottom.value.scrollIntoView({ behavior: 'smooth' })
    }
  })
}

// 构建BLAST数据库
const handleBuildBlast = async () => {
  Modal.confirm({
    title: '确认构建BLAST数据库',
    content: '构建过程可能需要较长时间，是否继续？',
    onOk: async () => {
      buildingBlast.value = true
      buildLogs.value = []
      addLog('开始构建BLAST数据库...', 'info')
      
      try {
        const response = await axiosInstance.post('/api/admin/build/blast')
        
        if (response.data.success) {
          message.success('BLAST数据库构建成功！')
          addLog('✓ BLAST数据库构建成功', 'info')
          if (response.data.output) {
            // 解析输出，添加关键日志
            const lines = response.data.output.split('\n')
            lines.forEach(line => {
              if (line.trim()) {
                const level = line.includes('ERROR') ? 'error' : 
                             line.includes('WARNING') ? 'warning' : 'info'
                addLog(line.trim(), level)
              }
            })
          }
        } else {
          message.error('构建失败')
          addLog('✗ BLAST数据库构建失败', 'error')
        }
        
        // 刷新状态
        await fetchDbStatus()
      } catch (error) {
        console.error('构建BLAST数据库失败:', error)
        const errorMsg = error.response?.data?.detail || error.message || '未知错误'
        message.error('构建失败: ' + errorMsg)
        addLog('✗ 构建失败: ' + errorMsg, 'error')
      } finally {
        buildingBlast.value = false
      }
    }
  })
}

// 构建Foldseek数据库
const handleBuildFoldseek = async () => {
  Modal.confirm({
    title: '确认构建Foldseek数据库',
    content: '构建过程可能需要较长时间，是否继续？',
    onOk: async () => {
      buildingFoldseek.value = true
      buildLogs.value = []
      addLog('开始构建Foldseek数据库...', 'info')
      
      try {
        const response = await axiosInstance.post('/api/admin/build/foldseek')
        
        if (response.data.success) {
          message.success('Foldseek数据库构建成功！')
          addLog('✓ Foldseek数据库构建成功', 'info')
          if (response.data.output) {
            // 解析输出，添加关键日志
            const lines = response.data.output.split('\n')
            lines.forEach(line => {
              if (line.trim()) {
                const level = line.includes('ERROR') ? 'error' : 
                             line.includes('WARNING') ? 'warning' : 'info'
                addLog(line.trim(), level)
              }
            })
          }
        } else {
          message.error('构建失败')
          addLog('✗ Foldseek数据库构建失败', 'error')
        }
        
        // 刷新状态
        await fetchDbStatus()
      } catch (error) {
        console.error('构建Foldseek数据库失败:', error)
        const errorMsg = error.response?.data?.detail || error.message || '未知错误'
        message.error('构建失败: ' + errorMsg)
        addLog('✗ 构建失败: ' + errorMsg, 'error')
      } finally {
        buildingFoldseek.value = false
      }
    }
  })
}

// 构建所有数据库
const handleBuildAll = async () => {
  Modal.confirm({
    title: '确认构建所有数据库',
    content: '将依次构建BLAST和Foldseek数据库，耗时较长，是否继续？',
    onOk: async () => {
      // 先构建BLAST
      buildingBlast.value = true
      buildLogs.value = []
      addLog('开始构建所有数据库...', 'info')
      addLog('第一步：构建BLAST数据库...', 'info')
      
      try {
        let response = await axiosInstance.post('/api/admin/build/blast')
        if (response.data.success) {
          addLog('✓ BLAST数据库构建完成', 'info')
          await fetchDbStatus()
        } else {
          throw new Error('BLAST构建失败')
        }
      } catch (error) {
        buildingBlast.value = false
        message.error('BLAST构建失败: ' + (error.response?.data?.detail || error.message))
        addLog('✗ BLAST数据库构建失败', 'error')
        return
      } finally {
        buildingBlast.value = false
      }
      
      // 再构建Foldseek
      buildingFoldseek.value = true
      addLog('第二步：构建Foldseek数据库...', 'info')
      
      try {
        let response = await axiosInstance.post('/api/admin/build/foldseek')
        if (response.data.success) {
          addLog('✓ Foldseek数据库构建完成', 'info')
          message.success('所有数据库构建成功！')
          await fetchDbStatus()
        } else {
          throw new Error('Foldseek构建失败')
        }
      } catch (error) {
        message.error('Foldseek构建失败: ' + (error.response?.data?.detail || error.message))
        addLog('✗ Foldseek数据库构建失败', 'error')
      } finally {
        buildingFoldseek.value = false
      }
    }
  })
}

// 格式化日期
const formatDate = (dateStr) => {
  if (!dateStr) return '-'
  try {
    const date = new Date(dateStr)
    return date.toLocaleString('zh-CN', {
      year: 'numeric',
      month: '2-digit',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit',
      second: '2-digit'
    })
  } catch {
    return dateStr
  }
}

// 格式化时间
const formatTime = (timestamp) => {
  if (!timestamp) return ''
  try {
    const date = new Date(timestamp)
    return date.toLocaleTimeString('zh-CN', { hour12: false })
  } catch {
    return timestamp
  }
}

// 日志级别图标
const getLevelIcon = (level) => {
  switch (level) {
    case 'error':
      return '❌'
    case 'warning':
      return '⚠️'
    case 'info':
    default:
      return 'ℹ️'
  }
}

onMounted(() => {
  fetchDbStatus()
})
</script>

<style scoped>
.admin-page {
  min-height: 100vh;
  background: #f5f7fa;
}

.content {
  padding: 24px;
  max-width: 1400px;
  margin: 0 auto;
}

.admin-container {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.header {
  text-align: center;
  margin-bottom: 8px;
}

.title {
  font-size: 32px;
  font-weight: 600;
  color: #2c3e50;
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
}

.subtitle {
  font-size: 16px;
  color: #909399;
  margin: 8px 0 0 0;
}

.status-card,
.action-card,
.log-card,
.help-card {
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  border: 1px solid #e4e7ed;
}

.status-card :deep(.ant-card-head-title),
.action-card :deep(.ant-card-head-title),
.log-card :deep(.ant-card-head-title),
.help-card :deep(.ant-card-head-title) {
  color: #2c3e50;
  font-weight: 600;
  font-size: 18px;
}

/* 终端样式 */
.terminal {
  background: #1e1e1e;
  border-radius: 4px;
  padding: 16px;
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  font-size: 13px;
  max-height: 400px;
  overflow-y: auto;
  color: #d4d4d4;
}

.log-entry {
  padding: 4px 0;
  display: flex;
  gap: 8px;
  line-height: 1.6;
}

.log-time {
  color: #858585;
  min-width: 80px;
}

.log-level {
  min-width: 24px;
}

.log-message {
  flex: 1;
}

.log-info .log-message {
  color: #d4d4d4;
}

.log-warning .log-message {
  color: #d4a72c;
}

.log-error .log-message {
  color: #f48771;
}

/* 滚动条样式 */
.terminal::-webkit-scrollbar {
  width: 8px;
}

.terminal::-webkit-scrollbar-track {
  background: #2d2d2d;
}

.terminal::-webkit-scrollbar-thumb {
  background: #555;
  border-radius: 4px;
}

.terminal::-webkit-scrollbar-thumb:hover {
  background: #777;
}

:deep(.ant-btn-primary) {
  background: #409eff;
  border-color: #409eff;
}
</style>

